﻿using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using RuYiAdmin.Net.Common.Global;
using RuYiAdmin.Net.Entity.BusinessDTO.SystemManagement;
using RuYiAdmin.Net.Service.BusinessService.Redis;
using RuYiAdmin.Net.Service.BusinessService.SystemManagement.ScheduleJob;
using StackExchange.Redis;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace RuYiAdmin.Net.WebApi.AppCode.FrameworkClass
{
    /// <summary>
    /// 分布式消息订阅器
    /// </summary>
    public class DistributedMessageSubscriber : IHostedService
    {
        /// <summary>
        /// 计划任务接口实例
        /// </summary>
        private readonly IScheduleJobService scheduleJobService;

        /// <summary>
        /// Redis服务接口实例
        /// </summary>
        private readonly IRedisService redisService;

        public DistributedMessageSubscriber(IScheduleJobService scheduleJobService,
                                            IRedisService redisService)
        {
            this.scheduleJobService = scheduleJobService;
            this.redisService = redisService;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            if (GlobalContext.QuartzConfig.SupportGroup)
            {
                this.redisService.SubscribeMessage(GlobalContext.QuartzConfig.ChanelName, new Action<RedisChannel, RedisValue>(async (channel, message) =>
                    {
                        var msg = JsonConvert.DeserializeObject<QuartzJobDTO>(message.ToString());
                        if (msg.GroupId != null && msg.GroupId == GlobalContext.QuartzConfig.GroupId)
                        {
                            switch (msg.Action)
                            {
                                case "Delete":
                                    await this.scheduleJobService.DeleteScheduleJobAsync(msg.JobId);
                                    this.scheduleJobService.Delete(msg.JobId);
                                    break;
                                case "Start":
                                    await this.scheduleJobService.StartScheduleJobAsync(msg.JobId);
                                    break;
                                case "Pause":
                                    await this.scheduleJobService.PauseScheduleJobAsync(msg.JobId);
                                    break;
                                case "Resume":
                                    await this.scheduleJobService.ResumeScheduleJobAsync(msg.JobId);
                                    break;
                                default: break;
                            }
                        }
                    }));
            }
            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }
    }
}
